package org.mtmi.ui.controls.popups;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Path;
import org.eclipse.swt.graphics.Point;
import org.mtmi.ui.GraphicUtil;
import org.mtmi.ui.M;
import org.mtmi.ui.controls.Button;
import org.mtmi.ui.controls.listeners.NumPadResponseListener;
import org.mtmi.ui.controls.listeners.TapAdapter;
import org.mtmi.ui.controls.listeners.TapEvent;
import org.mtmi.ui.scenes.COLOR;
import org.mtmi.ui.scenes.FontManager;
import org.mtmi.ui.scenes.Scene;

public class NumPadPopup extends Popup {

	private final static int vSpan = 2;
	private final static int hSpan = 2;
	private final static int hMargin = 20;
	private final static int vMargin = 4;
	private final static int buttonWidth = 100;
	private final static int buttonHeight = 100;
	private static final int feedBackHeight = 100;
	
	private Button one;
	private Button two;
	private Button three;
	private Button four;
	private Button five;
	private Button six;
	private Button seven;
	private Button eight;
	private Button nine;
	private Button zero;
	private Button ok;
	private Button bckSpace;
	protected String text;
	private List<NumPadResponseListener> listeners;

	public NumPadPopup(Scene scene, int flags ) {
		super( scene, flags );
		listeners = new ArrayList<NumPadResponseListener>();
		text = ""; //$NON-NLS-1$
		createButtons();
	}

	public void addNumPadResponseListener(NumPadResponseListener l) {
		if(!listeners.contains(l)) {
			listeners.add(l);
		}
	}
	
	public void removeNumPadResponseListener(NumPadResponseListener l) {
		listeners.remove(l);
	}
	
	private void createButtons() {
		Scene scene = getScene();
		int x = (scene.getSize().x - (3*buttonWidth+2*hSpan))/2;
		int y = scene.getSize().y/4+feedBackHeight;
		seven = createNumButton(7);
		seven.setLocation(x, y+vMargin);
		eight = createNumButton(8);
		eight.setLocation(seven.getLocation().x+seven.getSize().x+hSpan, y+vMargin);
		nine = createNumButton(9);
		nine.setLocation(eight.getLocation().x+eight.getSize().x+hSpan, y+vMargin);
		four = createNumButton(4);
		y+=nine.getSize().y+vSpan;
		four.setLocation(x, y+vMargin);
		five = createNumButton(5);
		five.setLocation(four.getLocation().x+four.getSize().x+hSpan, y+vMargin);
		six = createNumButton(6);
		six.setLocation(five.getLocation().x+five.getSize().x+hSpan, y+vMargin);
		one = createNumButton(1);
		y+=six.getSize().y+vSpan;
		one.setLocation(x, y+vMargin);
		two = createNumButton(2);
		two.setLocation(one.getLocation().x+one.getSize().x+hSpan, y+vMargin);
		three = createNumButton(3);
		three.setLocation(two.getLocation().x+two.getSize().x+hSpan, y+vMargin);
		y+=three.getSize().y+vSpan;
		bckSpace = new Button(scene, flags & M.SCENE_EDITOR_CONTROL );
		bckSpace.setText("Del");
		bckSpace.setSize(new Point(buttonWidth, buttonHeight));
		bckSpace.setLocation(x, y+vMargin);
		bckSpace.addTapListener(new TapAdapter() {
			@Override
			public void controlTappedDown(TapEvent event) {
				if (text.length() >= 1) {
					text = text.substring(0, text.length() - 1);
					redraw();
				}			
			}
		});
		zero = createNumButton(0);
		zero.setLocation(bckSpace.getLocation().x+bckSpace.getSize().x+hSpan, y+vMargin);
		ok = new Button(scene, flags & M.SCENE_EDITOR_CONTROL );
		ok.setText("Ok");
		ok.setSize(new Point(buttonWidth, buttonHeight));
		ok.setLocation(zero.getLocation().x+zero.getSize().x+hSpan, y+vMargin);
		ok.addTapListener(new TapAdapter() {
			@Override
			public void controlTappedDown(TapEvent event) {
				terminate();
			}
		});
	}
	
	protected void terminate() {
		for (NumPadResponseListener l : listeners) {
			l.valueSet(text == null || text.length()==0 ? 0 : Integer.parseInt(text));
		}
		zero.dispose();
		one.dispose();
		two.dispose();
		three.dispose();
		four.dispose();
		five.dispose();
		six.dispose();
		seven.dispose();
		eight.dispose();
		nine.dispose();
		bckSpace.dispose();
		ok.dispose();
		dispose();
	}

	private Button createNumButton(final int value) {
		Button b = new Button( getScene(), flags & M.SCENE_EDITOR_CONTROL );
		b.setText(String.valueOf(value));
		b.setSize(new Point(buttonWidth, buttonHeight));
		b.addTapListener(new TapAdapter() {
			@Override
			public void controlTappedDown(TapEvent event) {
				if(text.length() > 0 || value > 0) {
					text+=String.valueOf(value);
					redraw();
				}
			}
		});
		return b;
	}

	/**
	 * Returns point where x stands for x position and y the width of the feedback area.
	 * @return
	 */
	private int computeFeedBackWidth() {
		int buttonsWidth = 3*buttonWidth+2*hSpan;
		int w = buttonsWidth;
		if(text != null) {
			GC gc = new GC(getScene());
			gc.setFont(FontManager.getInstance().getNormalFont());
			Point point = gc.stringExtent(text);
			gc.dispose();
			w = Math.max(point.x+2*hMargin, w);
		} 
		return w;
	}

	@Override
	public void paintContent(GC gc, int width, int height) {
		gc.setForeground( COLOR.sceneFg );
		gc.setBackground( COLOR.sceneBg );
		gc.setFont( FontManager.getInstance().getNormalFont() );
		gc.setLineWidth(4);
		int fbw = computeFeedBackWidth();
		int y = getScene().getSize().y/4;
		int x = (getScene().getSize().x - fbw)/2;
		Path valueFrame = GraphicUtil.getRoundRectangle(gc, x, y, fbw, feedBackHeight, 50, 50);
		gc.fillPath(valueFrame);
		if(text != null && text.trim().length() > 0) {
			gc.drawText(text, x+fbw-hMargin-gc.stringExtent(text).x, y+20);
		}
		gc.drawPath(valueFrame);
	}

	@Override
	public String toString() {
		return "Numeric pad"; //$NON-NLS-1$
	}
}
